package org.jradweb.core.beans;

import java.beans.PropertyEditor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jradweb.core.utils.BeanUtils;
import org.jradweb.core.utils.JPropertyEditorRegistry;
import org.springframework.beans.PropertyEditorRegistry;

public class JDataBinder implements DataBinder {
	private final static Log log = LogFactory.getLog(JDataBinder.class);

	private PropertyEditorRegistry propertyEditorRegistry = new JPropertyEditorRegistry();

	protected PropertyEditorRegistry getPropertyEditorRegistry() {
		return propertyEditorRegistry;
	}

	protected void setPropertyEditorRegistry(
			PropertyEditorRegistry propertyEditorRegistry) {
		this.propertyEditorRegistry = propertyEditorRegistry;
	}

	public JDataBinder() {

	}

	public void bind(Object target, Map<String,Object> map) {
		
	}
	/**
	 * 
	 * @param target
	 * @param propertyName
	 * @param propertyValue
	 * @deprecated
	 */
	protected void setPropertyValue(Object target, String propertyName,
			Object propertyValue) {
		String[] props = org.apache.commons.lang.StringUtils.split(
				propertyName, '.');
		List<Method> methods = BeanUtils
				.getSetMethods(props, target.getClass());
		if (methods.isEmpty() || propertyValue == null) {
			return;
		}
		Object currentObj = target;
		for (int i = 0; i < props.length - 1; i++) {
			Object subObj = BeanUtils.getPropertyValue(currentObj, props[i]);
			if (subObj == null) {
				// TODO move this logic to BeanUtils
				Method method = methods.get(i);
				Class returnType = method.getParameterTypes()[0];
				try {
					subObj = returnType.newInstance();
					BeanUtils.setPropertyValue(currentObj, props[i], subObj);
				} catch (InstantiationException e) {
					throw new RuntimeException(e);
				} catch (IllegalAccessException e) {
					throw new RuntimeException(e);
				}
			}
			currentObj = subObj;
		}

		// set value
		int lastIndex = props.length - 1;
		String prop = props[lastIndex];
		Method method = methods.get(lastIndex);
		Class paramType = method.getParameterTypes()[0];

		PropertyEditor pe = this.propertyEditorRegistry.findCustomEditor(
				paramType, null);
		if(pe == null&& JPropertyEditorRegistry.class.isInstance(this.propertyEditorRegistry)){
			JPropertyEditorRegistry pers=(JPropertyEditorRegistry)this.propertyEditorRegistry;
//			pers.
			pe=pers.getDefaultEditor(paramType);
		}
		
		if (pe == null) {
			String message = "No property editor found for Class \""
					+ paramType.getName()
					+ "\" when seting property value of \"" + propertyName
					+ "\" to taget Class \"" + target.getClass().getName()
					+ "\"";
			// TODO create NoPropertyEditorExcpetion
			throw new java.lang.RuntimeException(message);
		}
		// cast and set string value
		if (String.class.isInstance(propertyValue)) {
			pe.setAsText((String) propertyValue);
			try {
				method.invoke(currentObj, pe.getValue());
			} catch (IllegalArgumentException e) {
				throw new RuntimeException(e);
			} catch (IllegalAccessException e) {
				throw new RuntimeException(e);
			} catch (InvocationTargetException e) {
				throw new RuntimeException(e);
			}
		}
		// TODO may be Sring[] or Inputstream
	}
}
